package cn.wl.crm.web.controller;

import cn.wl.AjaxResult;
import cn.wl.HttpClientUtils;
import cn.wl.WxConstants;
import cn.wl.crm.domain.Employee;
import cn.wl.crm.domain.WxUser;
import cn.wl.crm.service.IEmployeeService;
import cn.wl.crm.service.IWxUserService;
import cn.wl.shiro.util.MyUsernamePasswordToken;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

@Controller
@CrossOrigin
public class LoginController {

    @Autowired
    private IWxUserService wxUserService;

    @Autowired
    private IEmployeeService employeeService;

    @RequestMapping(value = "/login",method = RequestMethod.GET)
    public String login(Model model){
        String codeUrl = WxConstants.CODEURL.replaceAll("APPID", WxConstants.APPID)
                .replaceAll("REDIRECT_URI", WxConstants.CALLBACK)
                .replaceAll("SCOPE", WxConstants.SCOPE);
        model.addAttribute("codeUrl",codeUrl);
        return "forward:/login.jsp";
    }

    //微信给我回调回来callback  /callback?code=sdfasdfa&state=111
    @RequestMapping(value = "/callback", method = RequestMethod.GET)
    public String callback(Model model,String code,String state) throws Exception {

        //获取返回code码

        //通过code获取Access Token  APPID SECRET CODE
        String accesstokenUrl = WxConstants.ACCESSTOKEURL.replaceAll("APPID", WxConstants.APPID)
                .replaceAll("SECRET", WxConstants.APPSECRET)
                .replaceAll("CODE", code);

        //发送请获取ak
        String akStr = HttpClientUtils.httpGet(accesstokenUrl, null);
        JSONObject akJson=  (JSONObject)JSON.parse(akStr);
        System.out.println("获取到信息："+akStr);
        String access_token =  akJson.getString("access_token");
        String openid = akJson.getString("openid");
        //通过Access Token获取用户信息

        String userInfoUrl = WxConstants.USERINFOURL.replaceAll("ACCESS_TOKEN", access_token)
                .replaceAll("OPENID", openid);

        String userInfoStr = HttpClientUtils.httpGet(userInfoUrl, null);
        System.out.println("用户信息："+userInfoStr);
        JSONObject userInfoJson=  (JSONObject)JSON.parse(userInfoStr);


        //判断该微信账号是否和用户进行绑定 查询t_wxuser empid 有值就说明绑定过
        //可以根据openid查询wxuser这个表 返回empid有值 就绑定过
        WxUser wxUser = wxUserService.getWxUserByOpenid(openid);
        if(wxUser == null){
            //把信息保存到wxUser表
            WxUser wxUser1 = new WxUser();
            wxUser1.setOpenid(openid);
            wxUser1.setHeadimgurl(userInfoJson.getString("headimgurl"));
            String province = userInfoJson.getString("province");
            String city = userInfoJson.getString("city");
            wxUser1.setAddress(province+city);
            wxUser1.setNickname(userInfoJson.getString("nickname"));
            wxUser1.setUnionid(userInfoJson.getString("unionid"));
            wxUserService.save(wxUser1);
            System.out.println("callback里面openid:"+openid);
            return "redirect:http://localhost:8080/#/binder?openid="+openid;
        }else{
            if(wxUser.getEmpid() != null && wxUser.getEmpid() != 0){
                //已经绑定过
                //免密登录
                AjaxResult ajaxResult = new AjaxResult();
                Employee employee = employeeService.queryOne(wxUser.getEmpid());
                MyUsernamePasswordToken token = new MyUsernamePasswordToken(employee.getName());
                ajaxResult=  login(token);
                Subject currentUser = SecurityUtils.getSubject();
                //获取当前用户的tokenid
                Serializable tokenid = currentUser.getSession().getId();
                System.out.println("tokenid"+tokenid);
                //获取当前用户的主题
                Employee employee1 = (Employee) currentUser.getPrincipal();
                System.out.println("employee1"+employee1);
                if(ajaxResult.getSuccess()){
                    //http://localhost:8080/#/user?userEmployee(name=1,%20password=null,%20email=12@qq.com,%20imgUrl=/upload/b88ea803-0869-4789-a7d6-b871bd12b90f.png,%20role_id=1,%20roleName=null)tokenid28a817df-8374-4da7-9dde-05dccb466ec4
                    return "redirect:http://localhost:8080/#/user?user"+employee1+"tokenid&"+tokenid;
                }
            }else{
                //跳转到绑定页面
                return "redirect:http://localhost:8080/#/binder?openid="+openid;
            }
        }


        return "forward:/login.jsp";
    }

    //绑定方法
    @RequestMapping(value="/binder",method = RequestMethod.POST)
    @ResponseBody
    public AjaxResult binder(@RequestBody Map mp){
        String username =(String) mp.get("username");
        String openid =(String) mp.get("openid");

        System.out.println("openid:"+openid);
        //根据username 查询Employee 取到id值
        Employee employee = employeeService.getByUsername(username);
        WxUser wxUser = new WxUser();
        wxUser.setOpenid(openid);
        wxUser.setEmpid(employee.getId());

        //完成绑定
        wxUserService.binder(wxUser);
        //通过shiro免密登录-不需要密码的登录
        AjaxResult ajaxResult = new AjaxResult();
        MyUsernamePasswordToken token = new MyUsernamePasswordToken(username);
        ajaxResult=  login(token);

        return ajaxResult;
    }

    @RequestMapping(value = "/login",method = RequestMethod.POST)
    @ResponseBody
    public AjaxResult login(@RequestBody Employee employee){
        System.out.println(employee);
        Subject currentUser = SecurityUtils.getSubject();
        AjaxResult ajaxResult = new AjaxResult();
        if(!currentUser.isAuthenticated()){
            try {
                MyUsernamePasswordToken token = new MyUsernamePasswordToken(employee.getName(), employee.getPassword());
                ajaxResult = login(token);
            } catch (UnknownAccountException e) {
                e.printStackTrace();
                return new AjaxResult("用户名不存在!");
            } catch (IncorrectCredentialsException e){
                e.printStackTrace();
                return new AjaxResult("密码错误!");
            } catch (AuthenticationException e){
                e.printStackTrace();
                return new AjaxResult("系统异常！");
            }

        }
        return ajaxResult;
    }

    // 抽取登录方法
    public AjaxResult login(MyUsernamePasswordToken token){
        Subject currentUser = SecurityUtils.getSubject();
        if(!currentUser.isAuthenticated()){
            try {
                currentUser.login(token);
            } catch (UnknownAccountException e) {
                e.printStackTrace();
                return new AjaxResult("用户名不存在!");
            } catch (IncorrectCredentialsException e){
                e.printStackTrace();
                return new AjaxResult("密码错误!");
            } catch (AuthenticationException e){
                e.printStackTrace();
                return new AjaxResult("系统异常！");
            }

        }
        //拿到认证之后的用户
        Employee employee1 = (Employee) currentUser.getPrincipal();
        employee1.setPassword(null);
        //除了返回登录成功与否,还要把登录的用户返回前端
        AjaxResult ajaxResult = new AjaxResult();
        HashMap hm = new HashMap();
        Serializable sessionId = currentUser.getSession().getId();
        hm.put("user",employee1);
        hm.put("token",sessionId);
        ajaxResult.setObjResult(hm);
        return ajaxResult;
    }

}
